<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    
</head>
<body>

    <!-- 
        call()  apply()   bind()
        都是来改变  函数内部的this指向
        call  apply 都会执行函数，并改变他内部的this指向
        call  apply传递参数方式不一样
        bind 不会执行函数，返回改变之后的函数，需要手动执行函数

        应用： call 经常用来实现继承(参数继承)
               apply也可以用来继承(数组继承)
               bind 最重要的是不会立即执行该函数，返回的是一个新函数

        继承：
            只能继承构造函数里面代码，没办法继承原型对象
            可以用原型继承方法：
            Driver.prototype=new People()
            再指回原来的对象
            Driver.prototype.constructor=Driver


     -->
   
    <script>
        // function ar()
        // {
        //     this.name='trump';
        //     console.log(this);
        // }
        // var driver={
        //     age:50
        // }
        // ar.call(driver)  //执行ar 并改变函数内部的this指向
        // console.log(window.name);

        //call()
        function People(name,age)   //构造函数
        {
            this.name=name   
            this.age=age;
        }
        var p=new People('biden',70)  //实例化people对象
        
        function Driver()   //构造函数
        {
            this.car=''
            People.call(this,'李司机',19)  //在调用people构造函数时，把people的this指向了目前driver的this，相当于继承
            this.driver=function()
            {
                console.log(this.name+'在开车，今年'+this.age);
            }
        }
        var d=new Driver()
        d.driver()




        //apply()
        function Animal(head,hair)
        {
            this.head=head;
            this.hair=hair;
            this.fit=function()
            {
                console.log(this.hair+'在嚎');
                return false
            }
        }
        Animal.prototype.run=function()
        {
            console.log(this.hair+'跑');
        }
        function Dog()
        {
            this.feet='4四只脚'
            Animal.apply(this,['圆圆头','金毛']); //改变了 Animal 内部的this指向  参数用 数组传递
        }
        var d=new Dog()
        {
            console.log(d.head,d.hair,d.feet);
            console.log(d.fit());
            // console.log(d.run());  //报错，因为实例化的对象是Dog而不是Animal
            //所以说不能使用父类的原型对象的方法
        }
        

        var y=Math.max.apply(Math,[1,2,3,4,5])  //求最大值
        console.log(y);

        function A()  //构造函数A
        {
            this.name='trump'
        }
        A.max=function(a,b,c,d)  //构造函数A的静态方法
        {
            console.log(this);
            console.log(a,b,c,d);
        }
        function B()
        {
            A.max.apply(window,[10,20,30,50]) //apply可以用来继承，改变max函数this指向，但是内部功能不受影响，内部默认this指向window
        }
        var b=new B()
        console.log(b);


        //bind()
        function Fruit(size,color)
        {
            this.size=size;
            this.color=color;
        }
        function Apple()
        {
            this.test='甜的'
            var f=Fruit.bind(this,'5寸','青苹果');//改变Fruit内部的this指向，但是没有执行该函数，返回le（return）改变之后的函数
            f()
        }
        var a=new Apple()
        console.log(a.test,a.size,a.color);
        console.log(a);
        //bind 可以改变定时器内部的this指向
        function P()
        {
            this.name='trump'
        }
        var p=new P()
        function callback()
        {
            console.log('这是定时任务',this,this.name);
        }
        var c=callback.bind(p)
        setTimeout(c,100)


        
       
    </script>
    
</body>
</html>